#include <stdlib.h>
#include <stdio.h>
#include <direct.h>
#include <string>
#include <conio.h>
#include <iostream>
#include "tiffuzzer.h"

#define OUTPUTDIR "TIFF"
#define NSIZE(x) sizeof(x)/sizeof(x[0])
 
void MakeHeader(char*, uint32);
void DirFuzz(char*, uint32, uint32);
uint32 CreateTifFile(char*,char*, char*, uint32, uint32);
 
 uint32 ttags[] = {
TIFFTAG_SUBFILETYPE,
TIFFTAG_OSUBFILETYPE,
TIFFTAG_IMAGEWIDTH,
TIFFTAG_IMAGELENGTH,
TIFFTAG_BITSPERSAMPLE,
TIFFTAG_COMPRESSION,
TIFFTAG_PHOTOMETRIC,
TIFFTAG_THRESHHOLDING,
TIFFTAG_CELLWIDTH,
TIFFTAG_CELLLENGTH,
TIFFTAG_FILLORDER,
TIFFTAG_DOCUMENTNAME,
TIFFTAG_IMAGEDESCRIPTION,
TIFFTAG_MAKE,
TIFFTAG_MODEL,
TIFFTAG_STRIPOFFSETS,
TIFFTAG_ORIENTATION,
TIFFTAG_SAMPLESPERPIXEL,
TIFFTAG_ROWSPERSTRIP,
TIFFTAG_STRIPBYTECOUNTS,
TIFFTAG_MINSAMPLEVALUE,
TIFFTAG_MAXSAMPLEVALUE,
TIFFTAG_XRESOLUTION,
TIFFTAG_YRESOLUTION,
TIFFTAG_PLANARCONFIG,
TIFFTAG_PAGENAME,
TIFFTAG_XPOSITION,
TIFFTAG_YPOSITION,
TIFFTAG_FREEOFFSETS,
TIFFTAG_FREEBYTECOUNTS,
TIFFTAG_GRAYRESPONSEUNIT,
TIFFTAG_GRAYRESPONSECURVE,
TIFFTAG_GROUP3OPTIONS,
TIFFTAG_T4OPTIONS,
TIFFTAG_GROUP4OPTIONS,
TIFFTAG_T6OPTIONS,
TIFFTAG_RESOLUTIONUNIT,
TIFFTAG_PAGENUMBER,
TIFFTAG_COLORRESPONSEUNIT,
TIFFTAG_TRANSFERFUNCTION,
TIFFTAG_SOFTWARE,
TIFFTAG_DATETIME,
TIFFTAG_ARTIST,
TIFFTAG_HOSTCOMPUTER,
TIFFTAG_PREDICTOR,
TIFFTAG_WHITEPOINT,
TIFFTAG_PRIMARYCHROMATICITIES,
TIFFTAG_COLORMAP,
TIFFTAG_HALFTONEHINTS,
TIFFTAG_TILEWIDTH,
TIFFTAG_TILELENGTH,
TIFFTAG_TILEOFFSETS,
TIFFTAG_TILEBYTECOUNTS,
TIFFTAG_BADFAXLINES,
TIFFTAG_CLEANFAXDATA,
TIFFTAG_CONSECUTIVEBADFAXLINES,
TIFFTAG_SUBIFD,
TIFFTAG_INKSET,
TIFFTAG_INKNAMES,
TIFFTAG_NUMBEROFINKS,
TIFFTAG_DOTRANGE,
TIFFTAG_TARGETPRINTER,
TIFFTAG_EXTRASAMPLES,
TIFFTAG_SAMPLEFORMAT,
TIFFTAG_SMINSAMPLEVALUE,
TIFFTAG_SMAXSAMPLEVALUE,
TIFFTAG_CLIPPATH,
TIFFTAG_XCLIPPATHUNITS,
TIFFTAG_YCLIPPATHUNITS,
TIFFTAG_INDEXED,
TIFFTAG_JPEGTABLES,
TIFFTAG_OPIPROXY,
TIFFTAG_JPEGPROC,
TIFFTAG_JPEGIFOFFSET,
TIFFTAG_JPEGIFBYTECOUNT,
TIFFTAG_JPEGRESTARTINTERVAL,
TIFFTAG_JPEGLOSSLESSPREDICTORS,
TIFFTAG_JPEGPOINTTRANSFORM,
TIFFTAG_JPEGQTABLES,
TIFFTAG_JPEGDCTABLES,
TIFFTAG_JPEGACTABLES,
TIFFTAG_YCBCRCOEFFICIENTS,
TIFFTAG_YCBCRSUBSAMPLING,
TIFFTAG_YCBCRPOSITIONING,
TIFFTAG_REFERENCEBLACKWHITE,
TIFFTAG_XMLPACKET,
TIFFTAG_OPIIMAGEID,
TIFFTAG_REFPTS,
TIFFTAG_REGIONTACKPOINT,
TIFFTAG_REGIONWARPCORNERS,
TIFFTAG_REGIONAFFINE,
TIFFTAG_MATTEING,
TIFFTAG_DATATYPE,
TIFFTAG_IMAGEDEPTH,
TIFFTAG_TILEDEPTH,
TIFFTAG_PIXAR_IMAGEFULLWIDTH,
TIFFTAG_PIXAR_IMAGEFULLLENGTH,
TIFFTAG_PIXAR_TEXTUREFORMAT,
TIFFTAG_PIXAR_WRAPMODES,
TIFFTAG_PIXAR_FOVCOT,
TIFFTAG_PIXAR_MATRIX_WORLDTOSCREEN,
TIFFTAG_PIXAR_MATRIX_WORLDTOCAMERA,
TIFFTAG_WRITERSERIALNUMBER,
TIFFTAG_COPYRIGHT,
TIFFTAG_RICHTIFFIPTC,
TIFFTAG_IT8SITE,
TIFFTAG_IT8COLORSEQUENCE,
TIFFTAG_IT8HEADER,
TIFFTAG_IT8RASTERPADDING,
TIFFTAG_IT8BITSPERRUNLENGTH,
TIFFTAG_IT8BITSPEREXTENDEDRUNLENGTH,
TIFFTAG_IT8COLORTABLE,
TIFFTAG_IT8IMAGECOLORINDICATOR,
TIFFTAG_IT8BKGCOLORINDICATOR,
TIFFTAG_IT8IMAGECOLORVALUE,
TIFFTAG_IT8BKGCOLORVALUE,
TIFFTAG_IT8PIXELINTENSITYRANGE,
TIFFTAG_IT8TRANSPARENCYINDICATOR,
TIFFTAG_IT8COLORCHARACTERIZATION,
TIFFTAG_IT8HCUSAGE,
TIFFTAG_IT8TRAPINDICATOR,
TIFFTAG_IT8CMYKEQUIVALENT,
TIFFTAG_FRAMECOUNT,
TIFFTAG_PHOTOSHOP,
TIFFTAG_EXIFIFD,
TIFFTAG_ICCPROFILE,
TIFFTAG_JBIGOPTIONS,
TIFFTAG_GPSIFD,
TIFFTAG_FAXRECVPARAMS,
TIFFTAG_FAXSUBADDRESS,
TIFFTAG_FAXRECVTIME,
TIFFTAG_FAXDCS,
TIFFTAG_STONITS,
TIFFTAG_FEDEX_EDR,
TIFFTAG_INTEROPERABILITYIFD,
TIFFTAG_DNGVERSION,
TIFFTAG_DNGBACKWARDVERSION,
TIFFTAG_UNIQUECAMERAMODEL,
TIFFTAG_LOCALIZEDCAMERAMODEL,
TIFFTAG_CFAPLANECOLOR,
TIFFTAG_CFALAYOUT,
TIFFTAG_LINEARIZATIONTABLE,
TIFFTAG_BLACKLEVELREPEATDIM,
TIFFTAG_BLACKLEVEL,
TIFFTAG_BLACKLEVELDELTAH,
TIFFTAG_BLACKLEVELDELTAV,
TIFFTAG_WHITELEVEL,
TIFFTAG_DEFAULTSCALE,
TIFFTAG_DEFAULTCROPORIGIN,
TIFFTAG_DEFAULTCROPSIZE,
TIFFTAG_COLORMATRIX1,
TIFFTAG_COLORMATRIX2,
TIFFTAG_CAMERACALIBRATION1,
TIFFTAG_CAMERACALIBRATION2,
TIFFTAG_REDUCTIONMATRIX1,
TIFFTAG_REDUCTIONMATRIX2,
TIFFTAG_ANALOGBALANCE,
TIFFTAG_ASSHOTNEUTRAL,
TIFFTAG_ASSHOTWHITEXY,
TIFFTAG_BASELINEEXPOSURE,
TIFFTAG_BASELINENOISE,
TIFFTAG_BASELINESHARPNESS,
TIFFTAG_BAYERGREENSPLIT,
TIFFTAG_LINEARRESPONSELIMIT,
TIFFTAG_CAMERASERIALNUMBER,
TIFFTAG_LENSINFO,
TIFFTAG_CHROMABLURRADIUS,
TIFFTAG_ANTIALIASSTRENGTH,
TIFFTAG_SHADOWSCALE,
TIFFTAG_DNGPRIVATEDATA,
TIFFTAG_MAKERNOTESAFETY,
TIFFTAG_CALIBRATIONILLUMINANT1,
TIFFTAG_CALIBRATIONILLUMINANT2,
TIFFTAG_BESTQUALITYSCALE,
TIFFTAG_RAWDATAUNIQUEID,
TIFFTAG_ORIGINALRAWFILENAME,
TIFFTAG_ORIGINALRAWFILEDATA,
TIFFTAG_ACTIVEAREA,
TIFFTAG_MASKEDAREAS,
TIFFTAG_ASSHOTICCPROFILE,
TIFFTAG_ASSHOTPREPROFILEMATRIX,
TIFFTAG_CURRENTICCPROFILE,
TIFFTAG_CURRENTPREPROFILEMATRIX,
TIFFTAG_DCSHUESHIFTVALUES,
TIFFTAG_FAXMODE,
TIFFTAG_JPEGQUALITY,
TIFFTAG_JPEGCOLORMODE,
TIFFTAG_JPEGTABLESMODE,
TIFFTAG_FAXFILLFUNC,
TIFFTAG_PIXARLOGDATAFMT,
TIFFTAG_DCSIMAGERTYPE,
TIFFTAG_DCSINTERPMODE,
TIFFTAG_DCSBALANCEARRAY,
TIFFTAG_DCSCORRECTMATRIX,
TIFFTAG_DCSGAMMA,
TIFFTAG_DCSTOESHOULDERPTS,
TIFFTAG_DCSCALIBRATIONFD,
TIFFTAG_ZIPQUALITY,
TIFFTAG_PIXARLOGQUALITY,
TIFFTAG_DCSCLIPRECTANGLE,
TIFFTAG_SGILOGDATAFMT,
TIFFTAG_SGILOGENCODE,
EXIFTAG_EXPOSURETIME,
EXIFTAG_FNUMBER,
EXIFTAG_EXPOSUREPROGRAM,
EXIFTAG_SPECTRALSENSITIVITY,
EXIFTAG_ISOSPEEDRATINGS,
EXIFTAG_OECF,
EXIFTAG_EXIFVERSION,
EXIFTAG_DATETIMEORIGINAL,
EXIFTAG_DATETIMEDIGITIZED,
EXIFTAG_COMPONENTSCONFIGURATION,
EXIFTAG_COMPRESSEDBITSPERPIXEL,
EXIFTAG_SHUTTERSPEEDVALUE,
EXIFTAG_APERTUREVALUE,
EXIFTAG_BRIGHTNESSVALUE,
EXIFTAG_EXPOSUREBIASVALUE,
EXIFTAG_MAXAPERTUREVALUE,
EXIFTAG_SUBJECTDISTANCE,
EXIFTAG_METERINGMODE,
EXIFTAG_LIGHTSOURCE,
EXIFTAG_FLASH,
EXIFTAG_FOCALLENGTH,
EXIFTAG_SUBJECTAREA,
EXIFTAG_MAKERNOTE,
EXIFTAG_USERCOMMENT,
EXIFTAG_SUBSECTIME,
EXIFTAG_SUBSECTIMEORIGINAL,
EXIFTAG_SUBSECTIMEDIGITIZED,
EXIFTAG_FLASHPIXVERSION,
EXIFTAG_COLORSPACE,
EXIFTAG_PIXELXDIMENSION,
EXIFTAG_PIXELYDIMENSION,
EXIFTAG_RELATEDSOUNDFILE,
EXIFTAG_FLASHENERGY,
EXIFTAG_SPATIALFREQUENCYRESPONSE,
EXIFTAG_FOCALPLANEXRESOLUTION,
EXIFTAG_FOCALPLANEYRESOLUTION,
EXIFTAG_FOCALPLANERESOLUTIONUNIT,
EXIFTAG_SUBJECTLOCATION,
EXIFTAG_EXPOSUREINDEX,
EXIFTAG_SENSINGMETHOD,
EXIFTAG_FILESOURCE,
EXIFTAG_SCENETYPE,
EXIFTAG_CFAPATTERN,
EXIFTAG_CUSTOMRENDERED,
EXIFTAG_EXPOSUREMODE,
EXIFTAG_WHITEBALANCE,
EXIFTAG_DIGITALZOOMRATIO,
EXIFTAG_FOCALLENGTHIN35MMFILM,
EXIFTAG_SCENECAPTURETYPE,
EXIFTAG_GAINCONTROL,
EXIFTAG_CONTRAST,
EXIFTAG_SATURATION,
EXIFTAG_SHARPNESS,
EXIFTAG_DEVICESETTINGDESCRIPTION,
EXIFTAG_SUBJECTDISTANCERANGE,
EXIFTAG_GAINCONTROL,
EXIFTAG_GAINCONTROL,
EXIFTAG_IMAGEUNIQUEID
 };
 
int main (int argc,char **argv) {
 
 char dummy[256];
 char *tif_data;
 uint32 data_size;
 uint32 offset;
 uint16 dir_count;
 TIFFDirEntry tdir;
  
 _mkdir(OUTPUTDIR);
 memset(dummy, 0x41, sizeof(dummy));
 
 data_size = sizeof(TIFFHeader)+sizeof(dummy)+sizeof(uint16)+(2*NSIZE(ttags)+4)*sizeof(TIFFDirEntry);
 
 printf("\n*** TIF file format fuzzer ***\n");
  
 tif_data = (char*)malloc(data_size);
 if (!tif_data) {
  printf("error: cannot malloc\n");
  return -1;
 }
 
 memset(tif_data, 0x00, data_size);
 
 offset = sizeof(TIFFHeader);
 MakeHeader(tif_data, sizeof(TIFFHeader)+sizeof(dummy));
 memcpy(tif_data+offset, dummy, sizeof(dummy));
 offset += sizeof(dummy);
 
 dir_count = 3;
 memcpy(tif_data+offset, &dir_count, sizeof(uint16));
 offset += sizeof(uint16);
 
 tdir.tdir_tag = 0x100;
 tdir.tdir_type = TIFF_SHORT;
 tdir.tdir_count = 1;
 tdir.tdir_offset = 600;
 
 memcpy(tif_data+offset, &tdir, sizeof(TIFFDirEntry));
 offset += sizeof(TIFFDirEntry);
 
 tdir.tdir_tag = 0x101;
 tdir.tdir_type = TIFF_SHORT;
 tdir.tdir_count = 1;
 tdir.tdir_offset = 400;
 
 memcpy(tif_data+offset, &tdir, sizeof(TIFFDirEntry));
 offset += sizeof(TIFFDirEntry);
 
 DirFuzz(tif_data, data_size, offset);
 
 free(tif_data);
 
 getch();
 return 0;
}
 
void MakeHeader(char* data, uint32 diroff) {
 TIFFHeader tiffh;
 
 tiffh.tiff_magic = 0x4949;
 tiffh.tiff_version = 42;
 tiffh.tiff_diroff = diroff;
 
 if (data)
  memcpy(data, &tiffh, sizeof(TIFFHeader));
}
 
uint32 CreateTifFile(char* dir,char* data, uint32 size) {
 FILE* fp;
 char file_name[128];
 
 sprintf(file_name, "%s\\%d.tif", dir);
 
 fp = fopen(file_name, "wb");
 if (!fp)
  return 0;
 
 if (fwrite(data,size,1,fp) != 1) {
  fclose(fp);
  return 0;
 }
 
 fclose(fp);
 
 return 1;
}
 
void DirFuzz(char* tif_data, uint32 data_size, uint32 offset) {
 uint32 count = 1;
 char dir[64];
for(uint32 i = 0; i < NSIZE(ttags); i++)
{
uint32 temp=ttags[i];
uint32 val=rand()%NSIZE(ttags);
ttags[i]=ttags[val];
ttags[val]=temp;
}
 std::string sdata;
 sdata+=tif_data;
 uint32 value32[] = {1,2,0xffffffff,0x80000000,0x40000000,0x100,0x10000000,0x40000};
printf("Press any key to start...\n");
getchar();
printf("Start!...\n");
for (uint32 i = 0; i < NSIZE(ttags); i++) {
sdata+=ttags[i];
uint32 rand1 = (rand()%TIFF_RATIONAL);
while (rand1<TIFF_BYTE)
{rand1 = (rand()%TIFF_RATIONAL);}
sdata+=rand1;
uint32 rand2 = (rand()%NSIZE(value32));
sdata+=value32[rand2];
uint32 rand3 = (rand()%NSIZE(value32));
sdata+=value32[rand3];
 }
 char * cdata;
 cdata = (char*)malloc(sdata.size());
 for(size_t i = 0; i < sdata.size(); i++)
{	    cdata[i] = sdata[i];	}
 if (!CreateTifFile(OUTPUTDIR,cdata,sdata.size())) {
		printf("error: cannot create file\n");
		return;
		}
 printf("Succeed.\n");
 delete[] cdata;
}